package game.module.club.dao;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import game.module.club.bean.Club;
import game.module.club.bean.ClubApply;
import game.module.club.bean.ClubDonateDetail;
import game.module.club.bean.ClubInviteBean;
import game.module.club.bean.ClubMember;

/**
 * @author: Pomelo.Lee
 * @date: 2017年8月29日 下午4:17:58
 */
public class ClubCache {

	private static Logger logger = LoggerFactory.getLogger(ClubCache.class);

	static class SingletonHolder {
		static ClubCache instance = new ClubCache();
	}

	public static ClubCache getInstance() {
		return SingletonHolder.instance;
	}

	private static AtomicInteger sequenceNumber = new AtomicInteger(0);

	private Map<Integer, Club> clubIdMap = new ConcurrentHashMap<>();
	private Map<String, Club> clubNameMap = new ConcurrentHashMap<>();

	private List<Club> listClub = new ArrayList<>();

	private Map<Integer, List<ClubDonateDetail>> map_donate = new ConcurrentHashMap<>();

	/**
	 * 俱乐部对应的申请人集合
	 */
	private Map<Integer, Map<Integer, ClubApply>> club_apply_map = new ConcurrentHashMap<>();

	/**
	 * 申请人对应的俱乐部集合
	 */
	private Map<Integer, Map<Integer, ClubApply>> member_apply_map = new ConcurrentHashMap<>();

	/**
	 * 邀请人集合map<playerid -->map<clubId,ClubInviteBean>>
	 */
	private Map<Integer, Map<Integer, ClubInviteBean>> invite_map = new ConcurrentHashMap<>();

	/**
	 * 获取俱乐部id生成
	 * 
	 * @return
	 */
	public static int nextClubId() {
		return sequenceNumber.incrementAndGet();
	}

	public void loadFromDb() {
		loadClubData();
		loadClubApplyData();
		loadClubInviteData();
	}

	private void loadClubInviteData() {
		long st = System.currentTimeMillis();
		List<ClubInviteBean> beanList = ClubDao.getInstance().listClubInviteBeanAll();
		try {
			for (ClubInviteBean bean : beanList) {
				if (!invite_map.containsKey(bean.getPlayerId())) {
					invite_map.put(bean.getPlayerId(), new ConcurrentHashMap<>());
				}
				invite_map.get(bean.getPlayerId()).put(bean.getClubId(), bean);
			}
			long et = System.currentTimeMillis();
			logger.info("loadClubInviteData num={},cost time={} ms", invite_map.size(), (et - st));
		} catch (Exception e) {
			logger.error("", e);
		}
	}

	private void loadClubApplyData() {
		long st = System.currentTimeMillis();
		List<ClubApply> beanList = ClubDao.getInstance().listAllClubApply();
		try {
			for (ClubApply clubApply : beanList) {
				addClubApply(clubApply);
			}
			long et = System.currentTimeMillis();
			logger.info("club apply num={},cost time={} ms", clubIdMap.size(), (et - st));
		} catch (Exception e) {
			logger.error("", e);
		}
	}

	private void loadJinDouDetailData(int clubId) {
		long st = System.currentTimeMillis();
		List<ClubDonateDetail> beanList = ClubDao.getInstance().listDonateDetailByClubId(clubId);
		try {
			if (beanList != null && beanList.size() > 0) {
				map_donate.put(clubId, beanList);
			}
			long et = System.currentTimeMillis();
			logger.info("club loadJinDouDetailData num={},cost time={} ms", beanList.size(), (et - st));
		} catch (Exception e) {
			logger.error("", e);
		}
	}

	/**
	 * 加载俱乐部数据
	 */
	private void loadClubData() {
		long st = System.currentTimeMillis();
		List<Club> beanList = ClubDao.getInstance().listValidAllClub();
		listClub = beanList;
		if (listClub == null) {
			listClub = new ArrayList<>();
		}
		int maxNum = 0;
		try {
			for (Club club : beanList) {
				List<ClubMember> listMember = ClubDao.getInstance().listMemberByClubId(club.getId());
				Map<Integer, ClubMember> mapMember = new ConcurrentHashMap<>();
				for (ClubMember cm : listMember) {
					mapMember.put(cm.getPlayerId(), cm);
				}
				club.setMapMember(mapMember);
				clubIdMap.put(club.getId(), club);
				clubNameMap.put(club.getName(), club);
				loadJinDouDetailData(club.getId());
				if (club.getId() > maxNum) {
					maxNum = club.getId();
				}
			}
			sequenceNumber = new AtomicInteger(maxNum);
			rankClub();
			long et = System.currentTimeMillis();
			logger.info("club num={},cost time={} ms", clubIdMap.size(), (et - st));
		} catch (Exception e) {
			logger.error("", e);
		}
	}

	public boolean isExistName(String clubName) {
		return clubNameMap.containsKey(clubName);
	}

	public void addClub(Club club) {
		if (clubIdMap.containsKey(club.getId())) {
			logger.error(" add club repeat ID clubid={},clubname={}", club.getId(), club.getName());
		} else {
			clubIdMap.put(club.getId(), club);
			listClub.add(club);
			rankClub();
		}
		if (clubNameMap.containsKey(club.getName())) {
			logger.error(" add club repeat NAME clubid={},clubname={}", club.getId(), club.getName());
		} else {
			clubNameMap.put(club.getName(), club);
		}
	}

	/**
	 * 活跃值高排序
	 */
	public void rankClub() {
		listClub.sort((Club c1, Club c2) -> c2.getLiveNessNum().compareTo(c1.getLiveNessNum()));
		int rank = 1;
		for (Club c : listClub) {
			c.setRank(rank);
			rank++;
		}
	}

	public List<Club> listClubByPage(int p, int size) {
		List<Club> list = new ArrayList<>();
		p = p < 1 ? 1 : p;
		int st = (p - 1) * size;
		int et = p * size;
		int max = listClub.size();
		if (st > max) {
			return list;
		}
		et = et > max ? max : et;
		for (int i = st; i < et; i++) {
			Club temp = listClub.get(i);
			if (temp != null) {
				list.add(temp);
			}
		}
		return list;
	}

	/**
	 * 获取俱乐部
	 * 
	 * @param clubId
	 * @return
	 */
	public Club getClubById(int clubId) {
		return clubIdMap.get(clubId);
	}

	public void removeClub(int clubId) {
		clubIdMap.remove(clubId);
		map_donate.remove(clubId);
		club_apply_map.remove(clubId);
		member_apply_map.values().remove(clubId);
		Iterator<Club> sListIterator = listClub.iterator();
		while (sListIterator.hasNext()) {
			Club club = sListIterator.next();
			if (club.getId() == clubId) {
				sListIterator.remove();
				break;
			}
		}
		rankClub();
	}

	public Map<Integer, ClubApply> getClubApplyMap(int clubId) {
		return club_apply_map.get(clubId);
	}

	public void removeApplyPlayerId(int clubId, int playerId) {
		Map<Integer, ClubApply> map = club_apply_map.get(clubId);
		if (map != null) {
			map.remove(playerId);
		}
		member_apply_map.remove(playerId);
	}

	public void rejectApplyPlayerId(int clubId, int playerId) {
		Map<Integer, ClubApply> map = club_apply_map.get(clubId);
		if (map != null) {
			map.remove(playerId);
		}
		member_apply_map.remove(playerId);
	}

	/**
	 * 是否已经在申请该俱乐部
	 * 
	 * @param clubId
	 * @param playerId
	 * @return
	 */
	public boolean isApplyIngClub(int clubId, int playerId) {
		Map<Integer, ClubApply> map = member_apply_map.get(playerId);
		if (map == null) {
			return false;
		}
		return map.containsKey(clubId);
	}

	public void addClubApply(ClubApply clubApply) {
		if (!club_apply_map.containsKey(clubApply.getClubId())) {
			Map<Integer, ClubApply> map = new ConcurrentHashMap<>();
			club_apply_map.put(clubApply.getClubId(), map);
		}
		club_apply_map.get(clubApply.getClubId()).put(clubApply.getPlayerId(), clubApply);

		if (!member_apply_map.containsKey(clubApply.getPlayerId())) {
			Map<Integer, ClubApply> map = new ConcurrentHashMap<>();
			member_apply_map.put(clubApply.getPlayerId(), map);
		}
		member_apply_map.get(clubApply.getPlayerId()).put(clubApply.getClubId(), clubApply);
	}

	public void addClubDonateDetail(ClubDonateDetail bean) {
		if (!map_donate.containsKey(bean.getClubId())) {
			map_donate.put(bean.getClubId(), new ArrayList<>());
		}
		map_donate.get(bean.getClubId()).add(bean);
	}

	public List<ClubDonateDetail> listJinDouDetailByClubId(int clubId, int p, int size) {
		List<ClubDonateDetail> list = new ArrayList<>();
		if (!map_donate.containsKey(clubId)) {
			return list;
		}
		p = p < 1 ? 1 : p;
		int st = (p - 1) * size;
		int et = p * size;

		List<ClubDonateDetail> allList = map_donate.get(clubId);
		int max = allList.size();
		if (st > max) {
			return list;
		}
		et = et > max ? max : et;
		et = et - 1;
		for (int i = et; i >= st; i--) {
			ClubDonateDetail temp = allList.get(i);
			if (temp != null) {
				list.add(temp);
			}
		}

		return list;
	}

	public ClubInviteBean getInviteBeanByPlayerId(int playerId, int clubId) {
		if (!invite_map.containsKey(playerId)) {
			return null;
		}
		return invite_map.get(playerId).get(clubId);
	}

	public boolean isContainsInvite(int playerId, int clubId) {
		if (!invite_map.containsKey(playerId)) {
			return false;
		}
		return invite_map.get(playerId).containsKey(clubId);
	}

	public void addInviteBean(ClubInviteBean bean) {
		if (!invite_map.containsKey(bean.getPlayerId())) {
			invite_map.put(bean.getPlayerId(), new ConcurrentHashMap<>());
		}
		invite_map.get(bean.getPlayerId()).put(bean.getClubId(), bean);
	}

	public static void main(String[] args) {

		for (int i = 1; i <= 20; i++) {
			ClubDonateDetail bean = new ClubDonateDetail();
			bean.setClubId(1);
			bean.setId(i);
			ClubCache.getInstance().addClubDonateDetail(bean);
		}

		List<ClubDonateDetail> list = ClubCache.getInstance().listJinDouDetailByClubId(1, 2, 8);
		for (ClubDonateDetail cdd : list) {
			System.out.println(cdd.getId());
		}

		for (int i = 1; i <= 20; i++) {
			Club club = new Club();
			club.setId(i);
			club.setLiveNessNum(i * 2L);
			club.setName("豆豆棋牌" + i);
			ClubCache.getInstance().addClub(club);
		}
		int p = 2;
		int size = 5;

		List<Club> clubList = ClubCache.getInstance().listClubByPage(p, size);
		for (Club club : clubList) {
			System.out.println(club.getId() + "=" + club.getLiveNessNum());
		}
		for (int i = 0; i < 10; i++) {
			System.out.println(nextClubId());
		}
	}

}
